#include "task.h"

#include "scheduler.h"

// struct task  task_constructor()
void task_constructor(struct task *self)
{
    // struct task self ;
    self->ref_count_t = -1;
#ifdef REUSE_GRAPH
    self->backup_ref = -1;
    self->reused = 0;
    self->stored = 0;
    self->is_base_task = 1;
#endif
    self->affinity_id = INIT_AFFINITY;
#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
    self->priority_id = 0;
#endif
    // self->spawn_order_id = 0;
    self->next = NULL;
    // self->extra_state = 0;
    // return self;
}
struct task task_constructor_id(int id)
{
    struct task self;
    self.ref_count_t = -1;
#ifdef REUSE_GRAPH
    self.backup_ref = -1;
    self.reused = 0;
    self.stored = 0;
    self.is_base_task = 1;
#endif
    self.affinity_id = id;
#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
    self.priority_id = 0;
#endif
    // self.spawn_order_id = 0;
    self.next = NULL;
    // self.extra_state = 0;
    return self;
}

void increment_ref_count(struct task *self) { ++(self->ref_count_t); }
int ref_count(struct task *self) { return self->ref_count_t; }

#ifdef CONCURRENT_CONSTRUCT_GRAPH
/*
inline void set_pre(struct task* self,int p){self->pre = p;}
inline int pre_count(struct task *self){return self->pre;}
*/
#endif

// for dag reuse
#ifdef REUSE_GRAPH
void store_ref_count(struct task *self) { self->backup_ref = self->ref_count_t; }
void restore_ref_count(struct task *self) { self->ref_count_t = self->backup_ref; }

void set_stored(struct task *self, int flag) { self->stored = flag; }
int get_stored(struct task *self) { return self->stored; }

void set_reused_flag(struct task *self, int flag) { self->reused = flag; }
int get_reused_flag(struct task *self) { return self->reused; }
#endif

void set_affinity_id(struct task *self, int id) { self->affinity_id = id; }
#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
int get_priority_id(struct task *self) { return self->priority_id; }
void set_priority_id(struct task *self, int id) { self->priority_id = id; }
#endif
/*int get_spawn_order_id(struct task* self)
{
    return self->spawn_order_id;
}
void set_spawn_order_id(struct task* self,int id)
{
    self->spawn_order_id = id;
}*/

/*struct virtual_table_ * virtual_table_vptr = NULL;
void register_virtualfunc_table(virtual_table_*  p)
{
    virtual_table_vptr = p;
}*/

void wait_for_all(struct task *self) { main_kernel_func(self); }

void init_spawn(struct task *t) { init_spawn_sche(t); }

void enqueue(struct task *t) { enqueue(t); }

void spawn(struct task *t) { spawn_to_id(t); }

void adjust_affinity_id(struct task *self, struct task *another_task)
{
    if (self->affinity_id == INIT_AFFINITY) {
        self->affinity_id != another_task->affinity_id;
        return;
    }
    if (self->affinity_id != another_task->affinity_id) {
        self->affinity_id = FOLLOW_AFFINITY;
    }
}
struct empty_task *empty_task_constructor()
{
#ifdef MEMORY_POOL
#ifdef USE_SIMD
#ifdef TARG_SW5
    struct empty_task *self = (struct empty_task *)acemesh_myalloc_aligned_32(sizeof(struct empty_task));
#elif TARG_SW9
    struct empty_task *self = (struct empty_task *)acemesh_myalloc_aligned_64(sizeof(struct empty_task));
#endif
#else
    struct empty_task *self = (struct empty_task *)acemesh_myalloc_aligned_16(sizeof(struct empty_task));
#endif
#else
#ifdef TARG_SW5
    struct empty_task *self = (struct empty_task *)malloc(sizeof(struct empty_task));
#elif TARG_SW9
    //struct empty_task* self = (struct empty_task*)libc_uncached_aligned_malloc(sizeof(struct empty_task));
    struct empty_task* self = (struct empty_task*)my_malloc_aligned(sizeof(struct empty_task));
#else
    assert(0);
#endif
#endif
#ifdef DEBUG
printf("empty_task_addr=%p\n",self);
#endif
    task_constructor(&(self->task_base));
    return self;
}

void empty_task_destructor(struct empty_task *p_empty_task) 
{
#ifndef MEMORY_POOL
#ifdef TARG_SW5
    free(p_empty_task);
#elif TARG_SW9
    //libc_uncached_aligned_free(p_empty_task);
    my_free_aligned(p_empty_task);
#else
    printf("losing free empty_task\n");
#endif
#endif
}
